package dakside.hacc.modules.transactions.trxman;

import dakside.hacc.core.config.Configuration;
import dakside.hacc.core.models.Currency;
import java.text.ParseException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Date;
import dakside.hacc.core.models.Transaction;
import dakside.hacc.core.models.TransactionType;
import org.dakside.utils.DateTimeHelper;
import org.dakside.duck.helpers.SwingHelper;
import org.dakside.utils.ResourceCentre;
import java.text.DecimalFormat;
import java.text.NumberFormat;


/*
 * TransactionDetailPanel.java
 *
 * Created on Dec 30, 2009, 10:27:45 PM
 */
/**
 *
 * @author michael
 */
public class TransactionDetailPanel extends javax.swing.JPanel {

    private static final Logger logger = Logger.getLogger(TransactionDetailPanel.class.getName());

    //TODO disable code text field and auto generate code for transaction
    /** Creates new form TransactionDetailPanel */
    public TransactionDetailPanel() {
        initComponents();
        refresh();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        lblDate = new javax.swing.JLabel();
        lblAmount = new javax.swing.JLabel();
        txtCode = new javax.swing.JTextField();
        txtAmount = new javax.swing.JTextField();
        lblNote = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        txtAreaNote = new javax.swing.JTextArea();
        lblType = new javax.swing.JLabel();
        comboType = new javax.swing.JComboBox();
        jLabel2 = new javax.swing.JLabel();
        comboCurrency = new javax.swing.JComboBox();
        txtDate = new com.toedter.calendar.JDateChooser();

        setPreferredSize(new java.awt.Dimension(430, 117));

        jLabel1.setText("Transaction Code");
        jLabel1.setName("lblCode"); // NOI18N

        lblDate.setText("Transaction Date");
        lblDate.setName("lblDate"); // NOI18N

        lblAmount.setText("Transaction Amount");
        lblAmount.setName("lblAmount"); // NOI18N

        txtCode.setEditable(false);
        txtCode.setName("txtCode"); // NOI18N
        txtCode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                txtCodeActionPerformed(evt);
            }
        });

        txtAmount.setName("txtAmount"); // NOI18N

        lblNote.setText("Transaction Note");
        lblNote.setName("lblNote"); // NOI18N

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        txtAreaNote.setColumns(20);
        txtAreaNote.setRows(5);
        txtAreaNote.setName("txtAreaNote"); // NOI18N
        jScrollPane1.setViewportView(txtAreaNote);

        lblType.setText("Transaction Type");
        lblType.setName("lblType"); // NOI18N

        comboType.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        comboType.setName("comboType"); // NOI18N

        jLabel2.setText("Currency");
        jLabel2.setName("jLabel2"); // NOI18N

        comboCurrency.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        comboCurrency.setName("comboCurrency"); // NOI18N

        txtDate.setName("txtDate"); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(lblDate)
                    .addComponent(lblAmount)
                    .addComponent(lblType)
                    .addComponent(lblNote)
                    .addComponent(jLabel1))
                .addGap(4, 4, 4)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(txtCode, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE)
                    .addComponent(comboType, javax.swing.GroupLayout.Alignment.TRAILING, 0, 310, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(txtAmount, javax.swing.GroupLayout.DEFAULT_SIZE, 169, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(comboCurrency, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(txtDate, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblAmount, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(txtAmount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2)
                    .addComponent(comboCurrency, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(lblType)
                    .addComponent(comboType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(lblDate)
                    .addComponent(txtDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(lblNote)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtCode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel1))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void txtCodeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtCodeActionPerformed
        // TODO add your handling code here:
}//GEN-LAST:event_txtCodeActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox comboCurrency;
    private javax.swing.JComboBox comboType;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel lblAmount;
    private javax.swing.JLabel lblDate;
    private javax.swing.JLabel lblNote;
    private javax.swing.JLabel lblType;
    private javax.swing.JTextField txtAmount;
    private javax.swing.JTextArea txtAreaNote;
    private javax.swing.JTextField txtCode;
    private com.toedter.calendar.JDateChooser txtDate;
    // End of variables declaration//GEN-END:variables

    void refresh() {
        Object previousSelected =
                (comboCurrency.getSelectedItem() instanceof Currency)
                ? comboCurrency.getSelectedItem() : Configuration.getCurrencyFactory().getDefaultCurrency();
        //load transaction types
        TransactionType[] types = TransactionManager.getInstance().getAllTransactionType();
        SwingHelper.initCombobox(comboType, types);
        //auto load base currency if needed
        Currency[] currencies = TransactionManager.getInstance().getAllCurrencies();
        SwingHelper.initCombobox(comboCurrency, currencies, previousSelected);
    }
    /**
     * transaction model
     */
    private Transaction transaction = null;

    /**
     * Set a transaction to panel to display and edit
     * @param trx to create new transaction, please pass a null value in
     */
    public void setTransaction(Transaction trx) {
        this.transaction = trx;
        //reset UI
        txtAmount.setText("");
        txtDate.setDate(new Date());
        txtAreaNote.setText("");
        txtCode.setText("");
        comboType.setSelectedIndex(-1);

        if (trx != null) {
            //XXX need to reconfirm if this format is correct
            txtAmount.setText(new java.text.DecimalFormat("0.00").format(trx.getAmount()));
            txtDate.setDate(trx.getTransactionDate());
            txtAreaNote.setText(trx.getNote());
            comboType.setSelectedItem(trx.getType());
            txtCode.setText(trx.getUuid());
            SwingHelper.comboSelect(comboCurrency, trx.getCurrency());
        }

        //auto load base currency if needed
        if (comboCurrency.getSelectedIndex() < 0) {
            SwingHelper.comboSelect(comboCurrency, TransactionManager.getInstance().getDefaultCurrency());
        }
    }

    /**
     * Notify user about invalid data
     * @param message
     */
    private Transaction invalid(String message_key) {
//        SwingHelper.alert(ResourceCentre.getInstance(this).getString(message_key),
//                ResourceCentre.getInstance(this).getString("invalid_header"));
        return null;
    }

    /**
     * Get user edited object
     * @return
     */
    public Transaction getTransaction() {
        try {
            /* Validate data
             * 1. amount is not null
             * 2. type must be selected
             * 3. date cannot be null
             */

            NumberFormat f = DecimalFormat.getInstance();
            double amount;
            if (txtAmount.getText().trim().isEmpty()) {
                return invalid("invalid_amount_blank");
            }
            try {
                amount = f.parse(txtAmount.getText()).doubleValue();
            } catch (ParseException ex) {
                logger.log(Level.SEVERE, "Invalid transaction amount", ex);
                return invalid("invalid_amount");
            }
            //2. check type
            if (!(comboType.getSelectedItem() instanceof TransactionType)) {
                return invalid("invalid_type");
            }
            TransactionType type = (TransactionType) comboType.getSelectedItem();
            //3. check date
            Date date = txtDate.getDate();
            if (date == null || !(comboType.getSelectedItem() instanceof TransactionType)) {
                return invalid("invalid_date");
            }

            //build transaction object to return
            if (this.transaction == null) {
                this.transaction = new Transaction();
            }    //
            this.transaction.setAmount(amount);
            this.transaction.setTransactionDate(date);
            this.transaction.setNote(txtAreaNote.getText());
            this.transaction.setType(type);
            this.transaction.setCurrency((Currency) comboCurrency.getSelectedItem());
        } catch (NumberFormatException ex) {
            Logger.getLogger(TransactionDetailPanel.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
        return this.transaction;

    }
}
